//
//  Node.hpp
//  Simulation
//
//  Created by Christopher Kemsley on 3/3/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef Simulation_Node_hpp
#define Simulation_Node_hpp

#include <ostream>
#include "SystemCDefinitions.hpp"

#include "URL.hpp"

#include "Codec.hpp"
#include "Settings.hpp"






struct	ModelVariant
{
	std::string	builderName ;
	std::string	instanceName ;
	URL			configURL ;
	
	
	ModelVariant  ( ) ;
	ModelVariant  ( ModelVariant const & copy ) ;
	~ModelVariant () ;
	
	bool			isComplete () ;
	ModelVariant&	operator=	( ModelVariant const & copy ) ;
	
	friend std::ostream&	operator<<	( std::ostream& stream , ModelVariant const & variant ) ;
	
	
private:
	friend class Model ;
	virtual sc_module_name const&	moduleName () const ;
} ;







class	Model : public sc_module
{
public:
	
	virtual ~Model () { }
	
	Model	( ModelVariant const & inIdentity ) ;
	
	ModelVariant const	identity ;
	
private:
	// defined, but not implemented (forceably disabled)
	Model () ;
	Model ( Model const & c ) ;
	Model ( sc_module_name const & n ) ;
} ;

// Prints the identity
std::ostream&	operator<<	( std::ostream & stream , Model* model ) ;







/*** Protected ***/

template <typename SettingsType>
struct	ConfiguredModel : public Model
{
	SettingsType	mConfig ;
	
	ConfiguredModel	( ModelVariant const & identity )
	:	Model	( identity )
	,	mConfig	( identity.instanceName )
		{
		URL url ( identity.configURL ) ;
		Codec :: decode<URL,Settings> ( url , mConfig ) ;
		}
} ;








/*** Private ***/

class ModuleFactory ;

struct	ConstructionVariant : public ModelVariant
{
	ConstructionVariant	( ModelVariant const & copy )
	:	ModelVariant(copy)
	,	mName ( copy.instanceName.c_str() ) { }
	
	sc_module_name	mName ;
	
	virtual sc_module_name const&	moduleName () const ;
} ;



#endif
